﻿using System;
using System.Web.Mvc;

namespace LAPI.Web.Controllers.Reservas
{
    /// <summary>
    /// Controlador para /Reservas/
    /// </summary>
    public class ReservasController : BaseController
    {
        #region /Reservas/MisReservas
        /// <summary>
        /// GET: /Reservas/MisReservas
        /// </summary>       
        /// <returns>View MisReservas.cshtml</returns>
        [HttpGet]
        public ActionResult MisReservas()
        {
            ActionResult resultado = comprobarErrorPermisoSesion();
            if (resultado == null)
            {
                LAPI.Business.Gestores.GestorReservas gestor = new Business.Gestores.GestorReservas();

                LAPI.Business.DatosSesion datosSesion = (LAPI.Business.DatosSesion)Session["datosSesion"];

                return View(gestor.ObtenerPorUsuario(idUsuario: datosSesion.getModelUsuario().IdUsuario));
            }

            return resultado;
        }
        #endregion

        #region /Reservas/ReservasPista
        /// <summary>
        /// GET: /Reservas/ReservasPista
        /// </summary>
        /// <param name="id">Identificador de la pista que estamos administrando</param>
        /// <returns>View ReservasPista.cshtml</returns>
        [HttpGet]
        public ActionResult ReservasPista(Int32 id)
        {
            ActionResult resultado = comprobarErrorPermisoAdminPista();
            if (resultado == null)
            {
                LAPI.Business.Gestores.GestorReservas gestor = new Business.Gestores.GestorReservas();

                LAPI.Business.DatosSesion datosSesion = (LAPI.Business.DatosSesion)Session["datosSesion"];
                ViewData["IdPista"] = id;
                return View(gestor.ObtenerPorPista(idPista: id));
            }

            return resultado;
        }
        #endregion

        #region Filtros Búsqueda

        /// <summary>
        /// POST: /Reservas/Buscar
        /// </summary>
        /// <param name="centroFilter">Filtro por centro deportivo</param>
        /// <param name="pistaFilter">Filtro por pista</param>
        /// <param name="deporteFilter">Filtro por deporte</param>
        /// <param name="fechaFilter">Filtro por fecha de reserva</param>
        /// <returns>_ListadoMisReservas.cshtml</returns>
        [HttpPost]
        public ActionResult Buscar(String centroFilter, String deporteFilter, String pistaFilter, String fechaFilter)
        {

            ActionResult resultado = comprobarErrorPermisoSesion();
            if (resultado == null)
            {
                LAPI.Business.Gestores.GestorReservas gestor = new Business.Gestores.GestorReservas();

                //Creamos el filtro con los parametros posibles
                System.Collections.Hashtable filtro = new System.Collections.Hashtable();
                if (!String.IsNullOrEmpty(centroFilter))
                    filtro.Add("centro", centroFilter);
                if (!String.IsNullOrEmpty(pistaFilter))
                    filtro.Add("pista", pistaFilter);
                if (!String.IsNullOrEmpty(deporteFilter))
                    filtro.Add("deporte", deporteFilter);
                if (!String.IsNullOrEmpty(fechaFilter))
                    filtro.Add("fecha", fechaFilter);

                LAPI.Business.DatosSesion datosSesion = (LAPI.Business.DatosSesion)Session["datosSesion"];

                return PartialView("_ListadoMisReservas", gestor.ObtenerBusqueda(filtroBusqueda: filtro, idUsuario: datosSesion.getModelUsuario().IdUsuario));
            }

            return resultado;
        }

        /// <summary>
        /// POST: /Reservas/BuscarParaPista
        /// </summary>
        /// <param name="deporteFilter">Filtro por deporte</param>
        /// <param name="fechaFilter">Filtro por fecha de reserva</param>
        /// <param name="idPista">Identificador único de la pista</param>
        /// <returns>_ListadoReservasPista.cshtml</returns>
        [HttpPost]
        public ActionResult BuscarParaPista(String deporteFilter, String fechaFilter, Int32 idPista)
        {

            ActionResult resultado = comprobarErrorPermisoAdminPista();
            if (resultado == null || idPista == 0)
            {
                LAPI.Business.Gestores.GestorReservas gestor = new Business.Gestores.GestorReservas();

                //Creamos el filtro con los parametros posibles
                System.Collections.Hashtable filtro = new System.Collections.Hashtable();
                if (!String.IsNullOrEmpty(deporteFilter))
                    filtro.Add("deporte", deporteFilter);
                if (!String.IsNullOrEmpty(fechaFilter))
                    filtro.Add("fecha", fechaFilter);

                LAPI.Business.DatosSesion datosSesion = (LAPI.Business.DatosSesion)Session["datosSesion"];

                return PartialView("_ListadoReservasPista", gestor.ObtenerBusquedaPorPista(filtroBusqueda: filtro, idPista: idPista));
            }

            return resultado;
        }


        #endregion

        /*################## SERVICIOS ##################*/

        #region /Reservas/getReservasPista

        /// <summary>
        /// GET: /Reservas/getReservasPista
        /// </summary>
        /// <param name="selectPista">Identificador único de la pista</param>
        /// <param name="selectCentro">Identificador único del centro deportivo</param>
        /// <param name="selectDeporte">Identificador único del deporte</param>
        /// <returns>String con el json de la respuesta</returns>
        [HttpGet]
        public String getReservasPista(Int32 selectCentro, Int32 selectDeporte, Int32 selectPista)
        {
            if (selectCentro < 1 || selectDeporte < 1 || selectPista < 1)
            {
                return String.Empty;
            }

            LAPI.Business.Acciones.AccGetReservas getter = new Business.Acciones.AccGetReservas();
            var items = getter.GetReservas(idPista: selectPista, idCentro: selectCentro, idDeporte: selectDeporte);

            LAPI.Business.Gestores.GestorPistas gestor = new Business.Gestores.GestorPistas();
            var datosPista = gestor.ObtenerPorID(IdPista: selectPista, IdCentroDeportivo: selectCentro);

            return LAPI.Data.Model.Reserva.toJson(models: items, auxModel: datosPista);
        }

        /// <summary>
        /// POST: /Reservas/postReservasPista
        /// </summary>
        /// <param name="horaInicio">Hora a la que comienza la reserva</param>
        /// <param name="horaFin">Hora a la que finaliza la reserva</param>
        /// <param name="pistaSel">Identificador único de la pista</param>
        /// <param name="centroSel">Identificador único del centro deportivo</param>
        /// <param name="deporteSel">Identificador único del deporte</param>
        /// <returns>String con el json de la respuesta</returns>
        [HttpPost]
        public String postReservasPista(String horaInicio, String horaFin, Int32 deporteSel, Int32 pistaSel, Int32 centroSel)
        {
            LAPI.Business.Acciones.ResultadoAccion resultado = null;

            //0. Comprobamos que haya sesión
            resultado = comprobarPermisoSesion();
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            //1. Validamos que podamos realizar la reserva           
            LAPI.Data.Model.Reserva model = new Data.Model.Reserva();
            model.horaInicio = Convert.ToDateTime(horaInicio);
            model.horaFinal = Convert.ToDateTime(horaFin);
            LAPI.Business.Acciones.AccValidarReserva validacion = new Business.Acciones.AccValidarReserva();
            resultado = validacion.ValidarReserva(datosReserva: model, idPista: pistaSel);
            if (resultado.getResultado() == Business.Acciones.TipoResultado.ERROR)
            {
                //informamos del error
                return resultado.ResultadoToJson();
            }

            //3. Todo ha ido bien, mostramos mensaje
            resultado = new Business.Acciones.ResultadoAccion();
            resultado.setResultado(Business.Acciones.TipoResultado.CORRECTO);
            resultado.addMensaje(
                mensaje: "Reserva realizada correctamente.",
                tipoMensaje: Business.Acciones.TipoMensaje.OK
            );
            return resultado.ResultadoToJson();

        }

        #endregion

        #region /Reservas/NuevaReserva
        /// <summary>
        /// GET: /Reservas/NuevaReserva
        /// </summary>       
        /// <returns>View NuevaReserva.cshtml</returns>
        /// <param name="horaInicio">Hora a la que comienza la reserva</param>
        /// <param name="horaFin">Hora a la que finaliza la reserva</param>
        /// <param name="pistaReserva">Descripción única de la pista</param>
        /// <param name="centroReserva">Descripción única del centro deportivo</param>
        /// <param name="deporteReserva">Descripción única del deporte</param>
        /// <param name="pistaSel">Identificador único de la pista</param>
        /// <param name="centroSel">Identificador único del centro deportivo</param>
        /// <param name="deporteSel">Identificador único del deporte</param>
        [HttpGet]
        public ActionResult NuevaReserva(String horaInicio, String horaFin, String deporteReserva, String pistaReserva, String centroReserva, Int32 deporteSel, Int32 pistaSel, Int32 centroSel)
        {
            ActionResult resultado = comprobarErrorPermisoSesion();
            if (resultado == null)
            {
                ViewBag.horaInicio = horaInicio;
                ViewBag.horaFin = horaFin;
                ViewBag.deporteReserva = deporteReserva;
                ViewBag.pistaReserva = pistaReserva;
                ViewBag.centroReserva = centroReserva;
                ViewBag.deporteSel = deporteSel;
                ViewBag.pistaSel = pistaSel;
                ViewBag.centroSel = centroSel;

                LAPI.Business.Acciones.AccGetReservas getter = new Business.Acciones.AccGetReservas();
                var datos = getter.GetImporteReserva(idPista: pistaSel, idCentro: centroSel, idDeporte: deporteSel);

                ViewBag.importe = datos["precio"];
                ViewBag.suplemento = datos["suplementoluz"];
                ViewBag.luz = Convert.ToBoolean(datos["luz"]);

                return View();
            }

            return resultado;
        }
        #endregion

        #region /Reservas/ConfirmarReserva
        /// <summary>
        /// GET: /Reservas/ConfirmarReserva
        /// </summary>       
        /// <returns>View ConfirmarReserva.cshtml</returns>
        /// <param name="horaInicio">Hora a la que comienza la reserva</param>
        /// <param name="horaFin">Hora a la que finaliza la reserva</param>
        /// <param name="importe">Importe de la reserva</param>
        /// <param name="luzSel">Valor booleano indicador de si selecciona luz artificial o no</param>
        /// <param name="pistaSel">Identificador único de la pista</param>
        /// <param name="centroSel">Identificador único del centro deportivo</param>
        /// <param name="deporteSel">Identificador único del deporte</param>
        [HttpGet]
        public ActionResult ConfirmarReserva(String horaInicio, String horaFin, Int32 deporteSel, Int32 pistaSel, Int32 centroSel, String importe, String luzSel)
        {
            ActionResult resultado = comprobarErrorPermisoSesion();
            if (resultado == null)
            {
                LAPI.Data.Model.Reserva model = new Data.Model.Reserva();
                model.horaInicio = Convert.ToDateTime(horaInicio);
                model.horaFinal = Convert.ToDateTime(horaFin);
                model.IdUsuario = ((LAPI.Business.DatosSesion)Session["datosSesion"]).getModelUsuario().IdUsuario;
                model.luz = Convert.ToBoolean(luzSel.Equals("on"));
                model.importe = Convert.ToDouble(importe);

                LAPI.Business.Acciones.AccCrearReserva crear = new Business.Acciones.AccCrearReserva();
                crear.CrearReserva(datosReserva: model, idPista: pistaSel, idDeporte: deporteSel);
                var gestor = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
                gestor.Abrir();
                long idReserva = gestor.ObtenerIdGenerado();
                gestor.CerrarParcial();

                var sandboxEnabled = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["paypal.sandbox"].ToString());
                var emailPayPal = sandboxEnabled ? System.Configuration.ConfigurationManager.AppSettings["paypal.sandbox.seller.id"].ToString() : System.Configuration.ConfigurationManager.AppSettings["paypal.seller.id"].ToString();

                LAPI.Data.Model.Paypal paypal = new Data.Model.Paypal();
                paypal.cmd = "_xclick";
                paypal.business = emailPayPal;

                if (sandboxEnabled)
                    ViewBag.actionURI = "https:/www.sandbox.paypal.com/cgi-gin/webscr";
                else
                    ViewBag.actionURI = "https://www.paypal.com/cgi-bin/webscr";

                paypal.@return = "";
                paypal.cancel_return = "";
                paypal.IPN_return = "";
                paypal.currency_code = "EUR";

                paypal.item_name = "(num:" + idReserva.ToString() + ") Reserva de pista deportiva " + horaInicio + ".";
                paypal.amount = importe;
                return View(paypal);
            }

            return resultado;
        }

        /// <summary>
        /// POST: /Reservas/ValidarReserva
        /// </summary>       
        /// <returns>True si se ha comprobado el pago. False si no se ha comprobado</returns>
        [HttpPost]
        public Boolean ValidarReserva()
        {
            //Post back to either sandbox or live
            String strSandbox = "https://www.sandbox.paypal.com/cgi-bin/webscr";
            String strLive = "https://www.paypal.com/cgi-bin/webscr";

            var sandboxEnabled = Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["paypal.sandbox"].ToString());
            System.Net.HttpWebRequest req = null;
            if (sandboxEnabled)
                req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strSandbox);
            else
                req = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(strLive);
            //Set values for the request back
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            byte[] param = Request.BinaryRead(HttpContext.Request.ContentLength);
            string strRequest = System.Text.Encoding.ASCII.GetString(param);
            strRequest = strRequest.Remove(0, strRequest.IndexOf("business"));
            strRequest += "&cmd=_notify-validate";
            req.ContentLength = strRequest.Length;


            //Send the request to PayPal and get the response
            System.IO.StreamWriter streamOut = new System.IO.StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII);
            streamOut.Write(strRequest);
            streamOut.Close();
            System.IO.StreamReader streamIn = new System.IO.StreamReader(req.GetResponse().GetResponseStream());
            string strResponse = streamIn.ReadToEnd();
            streamIn.Close();

            if (strResponse == "VERIFIED")
            {
                //check the payment_status is Completed
                //check that txn_id has not been previously processed
                //check that receiver_email is your Primary PayPal email
                //check that payment_amount/payment_currency are correct
                //process payment
            }
            else if (strResponse == "INVALID")
            {
                //log for manual investigation
            }
            else
            {
                //log response/ipn data for manual investigation
            }
            return true;
        }
        #endregion
    }
}
